package com.countertack.ssh;

import java.io.InputStream;

import org.apache.commons.vfs2.provider.sftp.SftpFileSystem;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class SSHManager {

	Session session;
	public boolean doReconnect = true;
	String userName;
	String password;
	String ipAddress;

	public SSHManager(String userName, String password, String ipAddress) {

		this.userName = userName;
		this.password = password;
		this.ipAddress = ipAddress;

	}

	public void connect() {

		if (session != null) {

			return;
		}

		JSch jsch = new JSch();

		try {

			session = jsch.getSession(userName.trim(), ipAddress.trim(), 22);

			session.setPassword(password.trim());

			java.util.Properties config = new java.util.Properties();

			config.put("StrictHostKeyChecking", "no");

			session.setConfig(config);

			session.setPassword(password.trim());

			session.connect();
			System.out.println(session.isConnected());
		} catch (Exception e) {

			System.out.println("unable to connect to ssh");
			e.printStackTrace();
		}
		startReconnectionThread();

	}

	private void reconnectToSession() {

		JSch jsch = new JSch();

		try {

			session = jsch.getSession(userName, ipAddress, 22);

			session.setPassword(password);

			java.util.Properties config = new java.util.Properties();

			config.put("StrictHostKeyChecking", "no");

			session.setConfig(config);

			session.setPassword(password);

			session.connect();
		} catch (Exception e) {
			System.out.println("unable to connect to ssh");
			e.printStackTrace();
		}

	}

	public void runCommand(String command) {

		try {
			if (session == null || !session.isConnected()) {

				reconnectToSession();

				if (session == null || !session.isConnected()) {

					System.out.println("unable to run command");
					return;

				}

			}

			Channel channel = session.openChannel("exec");

			channel.setInputStream(null);

			channel.setOutputStream(System.out);
			System.out.println("command>>>>" + command);
			((ChannelExec) channel).setCommand(command);

			channel.connect();

			InputStream in = channel.getInputStream();

			byte[] tmp = new byte[1024];

			while (true) {

				while (in.available() > 0) {

					int i = in.read(tmp, 0, 1024);

					if (i < 0)

						break;

					System.out.print(new String(tmp, 0, i));

				}

				if (channel.isClosed()) {

					System.out
							.println("exit-status:" + channel.getExitStatus());

					break;

				}

				try {

					Thread.sleep(1000);

				} catch (Exception ee) {

				}

			}

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	// cd C:\Windows && dir /b /a-d

	public String returnCommandOutPut(String command) {
		String cmdOutput = null;
		StringBuffer outPut = new StringBuffer();
		try {
			if (session == null || !session.isConnected()) {

				reconnectToSession();

				if (session == null || !session.isConnected()) {

					System.out.println("unable to run command");
					return null;

				}

			}

			Channel channel = session.openChannel("exec");

			channel.setInputStream(null);

			channel.setOutputStream(System.out);

			((ChannelExec) channel).setCommand(command);

			channel.connect();

			InputStream in = channel.getInputStream();

			byte[] tmp = new byte[1024];

			while (true) {

				while (in.available() > 0) {

					int i = in.read(tmp, 0, 1024);

					if (i < 0)

						break;

					cmdOutput = new String(tmp, 0, i);
					outPut.append(cmdOutput);
					System.out.print(cmdOutput);

				}

				if (channel.isClosed()) {

					System.out
							.println("exit-status:" + channel.getExitStatus());

					break;

				}

				try {

					Thread.sleep(1000);

				} catch (Exception ee) {

				}

			}

		} catch (Exception e) {

			e.printStackTrace();

		}
		return outPut.toString();

	}

	/*public String returnNtosCommandOutPut(String command) {
		String cmdOutput = null;
		StringBuffer outPut = new StringBuffer();
		try {
			if (session == null || !session.isConnected()) {

				reconnectToSession();

				if (session == null || !session.isConnected()) {

					System.out.println("unable to run command");
					return null;

				}

			}

			Channel channel = session.openChannel("exec");

			channel.setInputStream(null);

			channel.setOutputStream(System.out);

			((ChannelExec) channel).setCommand(command);

			channel.connect();

			InputStream in = channel.getInputStream();

			byte[] tmp = new byte[1024];
			Thread.sleep(120000);
			while (true) {

				while (in.available() > 0) {

					int i = in.read(tmp, 0, 1024);

					if (i < 0)

						break;

					cmdOutput = new String(tmp, 0, i);
					outPut.append(cmdOutput);
					System.out.print(cmdOutput);

				}

				if (channel.isClosed()) {

					System.out
							.println("exit-status:" + channel.getExitStatus());

					break;

				}

				try {

					Thread.sleep(1000);

				} catch (Exception ee) {

				}

			}

		} catch (Exception e) {

			e.printStackTrace();

		}
		return outPut.toString();

	}
*/
	private void startReconnectionThread() {

		new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {

					try {
						Thread.sleep(30000);
					} catch (Exception e) {

						e.printStackTrace();
					}
					if (!doReconnect) {

						break;

					}
					if (session == null || !session.isConnected()) {
						try {

							reconnectToSession();
							System.out.println("Reconnected to ssh session");

						} catch (Exception e) {

							e.printStackTrace();

						}

					}

				}

			}
		}).start();

	}

	public void copyFile(String source, String destination) {
		try {
			if (session == null || !session.isConnected()) {

				reconnectToSession();

				if (session == null || !session.isConnected()) {

					System.out.println("unable to copy file");

					return;

				}

			}

			Channel channel = session.openChannel("sftp");
			channel.connect();
			ChannelSftp channelSftp = (ChannelSftp) channel;

			try {

				channelSftp.put(source, destination);
				

			} catch (Exception e) {
				e.printStackTrace();
				// TODO Auto-generated catch block e.printStackTrace();
			}

		} catch (Exception e) {

			e.printStackTrace();

		}

	}

	
	public void downloadFile(String source, String destination) {
		try {
			if (session == null || !session.isConnected()) {

				reconnectToSession();

				if (session == null || !session.isConnected()) {

					System.out.println("unable to downloadF file");

					return;

				}

			}

			Channel channel = session.openChannel("sftp");
			channel.connect();
			ChannelSftp channelSftp = (ChannelSftp) channel;

			try {
				channelSftp.get(source, destination);
				

			} catch (Exception e) {
				e.printStackTrace();
				// TODO Auto-generated catch block e.printStackTrace();
			}

		} catch (Exception e) {

			e.printStackTrace();

		}

	}
	
	public void closeSession() {

		if (session != null && session.isConnected()) {

			try {

				session.disconnect();

			} catch (Exception e) {

				e.printStackTrace();

			}

		}

	}

	public static void main(String[] args) throws Exception {

		SSHManager ssh = new SSHManager("user", "password1", "10.140.63.108");

		ssh.connect();

	}

}
